package ProducersAndConsumers;

public class TestProductCustmoer {
    public static void main(String[] args) {
        Shop shop = new Shop();//共享资源对象
        Thread p = new Thread(new Product(shop),"生产者");
        Thread c = new Thread(new Product(shop),"消费者");
        p.start();
        c.start();
//        p.run();
//        c.run();
    }
}
//商品
class Goods{
private  Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Goods(Integer id) {
        this.id = id;
    }
}
class Shop{
Goods goods;
boolean flag;//标识商品是否充足
//生产者调用存的方法
public synchronized void saveGoods(Goods goods) throws InterruptedException {//对商场的购买方法加锁
//第一步判断商品是否充足
    if (flag == true) {
        //商品充足,生产者进入等待,等待消费者消费
        System.out.println("商品充足,生产者要等待");
        this.wait();
    }
    //商品不充足,生产者生成商品,存入商城
    System.out.println(Thread.currentThread().getName()+
    "生产者在商城里存放"+goods.getId());
    this.goods=goods;
    flag =true;//已经有商品,消费者可以购买商品
    this.notifyAll();//将等待队列的消费者全部唤醒.购买商品
}
//消费者使用的取的方法
public synchronized void  getGoods(Goods goods) throws InterruptedException {//对商城的消费方法加锁
    if (flag == false) {//没有商品,消费者就要等待
        System.out.println("商品不充足,消费者要等待了");
    this.wait();//消费者进入等待队列,等待生产者购买商品

    }
    //正常购买商品
    System.out.println(Thread.currentThread().getName()+"购买了"+goods.getId()+"的商品");
    //商品买完了,标识没货了
    this.goods=null;
    flag =false;
    //唤醒生产者去生产商品
    this.notifyAll();
}
}
//生产者消费的线程
class Product implements Runnable {
    Shop shop;//商场

    public Product(Shop shop) {
        this.shop = shop;
    }

    @Override
    public void run() {
//通过循环生产商品存放到shop
        for (int i = 0; i <30 ; i++) {
            //生产者线程调用存商品的方法,存一个商品对象
            try {
                this.shop.saveGoods(new Goods(i));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//消费者的线程
class Customer implements Runnable {
    Shop shop;//商场

    public Customer(Shop shop) {
        this.shop = shop;
    }

    @Override
    public void run() {
        //消费者调用取商品的方法,取一个商品
        for (int i = 0; i <30 ; i++) {
            try {
                this.shop.getGoods(new Goods(i));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}